home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CD ROM Paradise Collection 4
/
CD ROM Paradise Collection 4 1995 Nov.iso
/
program
/
vgl20.zip
/
VGLKEY.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-05-14
|
6KB
|
136 lines
/*****************************************************************************
VGLKEY.C
This module supplies two functions. The first turns on an int 9 handler
that allows you to test for multiple keys being held down, very useful in
a game situation! The second function simply restores the original int 9
handler.
Mark
morley@camosun.bc.ca
*****************************************************************************/
#include <dos.h>
#include "vgl.h"
struct KEYMAP /* This holds a list of key scan */
{ /* codes that we want to trap. */
unsigned char downcode; /* Code when key is pressed */
unsigned char upcode; /* Code when key is released */
}
Keys[VGL_NUMKEYS] = /* Add keys here!!! */
{
VGL_UPARROW,
VGL_DOWNARROW,
VGL_LEFTARROW,
VGL_RIGHTARROW
};
char vglKeyStatus[VGL_NUMKEYS]; /* An array to hold key status */
/* info. One byte per key defined */
/* above. If a key is currently */
/* being held down, its byte in */
/* this list will be decimal 1, */
/* otherwise it will be a 0. The */
/* first key in the list above */
/* maps to vglKeyStatus[0], the */
/* second to vglKeyStatus[1], etc */
static void interrupt (*oldint1b)();
static void interrupt (*oldint23)();
static void interrupt (*oldint9)(); /* Old int 9 handler */
static int NumLock; /* Used to remember if NumLock was */
/* active when we started. */
/* Pointer to shift status area */
static unsigned char far* kbdata = (unsigned char far*) MK_FP( 0x40, 0x17 );
/* Macro to acknowledge a keystroke*/
#define ACKKEY al = ah = inportb( 0x61 ); \
al |= 0x80; \
outportb( 0x61, al ); \
outportb( 0x61, ah ); \
outportb( 0x20, 0x20 )
void interrupt int1b( void ) {}
void interrupt int23( void ) {}
/*****************************************************************************
The int 9 handler. This routine fires everytime a key is pressed or
released on the keyboard. Since each key generates a unique (more or less)
scan code both when it's pressed, and a different one when it's released,
we can actually have multiple keys being held down simultaneously.
This routine simple loops through the list you define above, checking the
current scan code against the up and down codes. If it matches one, then
it sets or resets the appropriate byte in the vglKeyStatus[] array.
*****************************************************************************/
void interrupt int9( void )
{
register i;
unsigned char al, ah, c;
c = inportb( 0x60 ); /* Get the scan code */
for( i = 0; i < VGL_NUMKEYS; i++ ) /* Loop through the table */
{
if( c == Keys[i].downcode ) /* Is it a downcode? */
{
ACKKEY; /* Acknowledge the keystroke */
vglKeyStatus[i] = 1; /* Set the status byte to 1 */
break; /* We're done! */
}
if( c == Keys[i].upcode ) /* Is it an upcode? */
{
ACKKEY; /* Acknowledge the keystroke */
vglKeyStatus[i] = 0; /* Reset the status byte to 0 */
break; /* We're done! */
}
}
if( i == VGL_NUMKEYS ) /* Otherwise, we call the original */
_chain_intr( oldint9 ); /* int 9 handler */
}
/*****************************************************************************
Called to start the trapping of keys. The current status of the NumLock
key is preserved, then NumLock is turned off. Don't forget to call
vglReleaseKeys() before your program exits!
*****************************************************************************/
vglTrapKeys()
{
int i;
for( i = 0; i < VGL_NUMKEYS; i++ ) /* Initialize the status bytes */
vglKeyStatus[i] = 0;
NumLock = (*kbdata & 32) == 32; /* Save the current numlock status */
*kbdata &= (255-32); /* Turn off numlock */
oldint9 = getvect( 0x09 ); /* Save the current int 9 handler */
oldint1b = getvect( 0x1b );
oldint23 = getvect( 0x23 );
setvect( 0x09, int9 ); /* Install out int 9 handler */
setvect( 0x1b, int1b );
setvect( 0x23, int23 );
return;
}
/*****************************************************************************
Stops the trapping of keys. NumLock is restored to its previous value.
IMPORTANT!!! If you previously called vglTrapKeys(), you **MUST** call
this routine before exiting your program or evil things may happen!
*****************************************************************************/
vglReleaseKeys()
{
setvect( 0x09, oldint9 ); /* Restore the old int 9 handler */
setvect( 0x1b, oldint1b );
setvect( 0x23, oldint23 );
if( NumLock ) /* Restore the numlock status */
*kbdata |= 32;
return;
}